package ogb;

import static org.junit.Assert.assertTrue;
import robocode.control.events.BattleCompletedEvent;
import robocode.control.events.TurnEndedEvent;
import robocode.control.testing.RobotTestBed;
import robocode.control.snapshot.IRobotSnapshot;

/**
 * Tests the maneuverability of DeaconBlues.
 * Based on sample code from http://code.google.com/p/robocode-pmj-dacruzer/
 * 
 * @author Branden Ogata
 *
 */
public class TestDeaconBluesCorners extends RobotTestBed {
  private int cornerVisits0 = 0;
  private int cornerVisits1 = 0;
  private int cornerVisits2 = 0;
  private int cornerVisits3 = 0;
  
  /**
   * Specifies SittingDuck and DeaconBlues as the robots involved in this test.
   * 
   * @return  The names of the robots in this match.
   * 
   */
  
  @Override
  public String getRobotNames() {
    return "sample.SittingDuck,ogb.DeaconBlues";
  }

  /**
   * Returns the number of rounds in this match.
   * 
   * @return  The number of rounds in this test.
   * 
   */
  
  @Override
  public int getNumRounds() {
    return 8;
  }
  
  /**
   * Each turn, check if DeaconBlues is in a corner; if so, then increment the corner counter.
   *
   * @param e The event that the game sends.
   * 
   */
  
  @Override
  public void onTurnEnded(TurnEndedEvent e) {
    // Current information about DeaconBlues
    IRobotSnapshot self = e.getTurnSnapshot().getRobots()[1];
    
    // Current position of DeaconBlues
    double xCoordinate = self.getX();
    double yCoordinate = self.getY();
    
    // The dimensions of a robot 
    double robotWidth = 40.0;
    double robotHeight = 40.0;
    
    // If in a corner, increment the counter for that corner
    if ((xCoordinate < robotWidth) && (yCoordinate < robotHeight)) {
      cornerVisits0++;
    }
    else if ((xCoordinate < robotWidth) && (height - robotHeight < yCoordinate)) {
      cornerVisits1++;
    }
    else if ((xCoordinate > width - robotWidth) && 
              (height - robotHeight < yCoordinate)) {
      cornerVisits2++;
    }
    else if ((xCoordinate > width - robotWidth) && (yCoordinate < robotHeight)) {
      cornerVisits3++;
    }
  }
  
  /**
   * When battle is concluded, compare the number of times that each corner was visited.
   * 
   * @param e The event that the game sends.
   */
  
  @Override
  public void onBattleCompleted(BattleCompletedEvent e) {
    double totalVisits = cornerVisits0 + cornerVisits1 + cornerVisits2 + cornerVisits3;
    
    // If the random method for movement is in fact random, then DeaconBlues should 
    // visit all of the corners more or less the same amount of times.
    // In practice, there are several reasons why a particular corner might not be
    // visited as often, especially if this robot remains at a corner for several "turns."
    assertTrue("Corner 0 Distribution " + cornerVisits0 + "/" + totalVisits, 
                Math.abs(cornerVisits0 / totalVisits) > 0.01);
    assertTrue("Corner 1 Distribution " + cornerVisits1 + "/" + totalVisits, 
                Math.abs(cornerVisits1 / totalVisits) > 0.01);  
    assertTrue("Corner 2 Distribution " + cornerVisits2 + "/" + totalVisits,
                Math.abs(cornerVisits2 / totalVisits) > 0.01);
    assertTrue("Corner 3 Distribution " + cornerVisits3 + "/" + totalVisits, 
                Math.abs(cornerVisits3 / totalVisits) > 0.01);
      
  }
}
